/* new Map是创建一个 Map 对象的实例，用于存储键值对集合
 const p = new Map();
p.set('a',111)
p.set(()=>{},33)
console.log(p)

console.log(p.get('a'))
console.log(p.size)
console.log(p.has("a"))
// p.delete("a")
p.clear();
console.log('p-----',p) */

/* const _set = new Set();
_set.add(1)
_set.add(2).add(5)
_set.add(2)
const del5 =  _set.delete(5)
const res =  _set.has(2)
_set.clear();
console.log('res',res)
console.log('set',_set)
console.log('del5',del5) */

/* 1. 创建一个对象(缓存列表)
2. on方法用来把回调函数fn都加到缓存列表中
3. emit 根据key值去执行对应缓存列表中的函数
4. off方法可以根据key值取消订阅 */
class EventEmitter {
  constructor() {
    this.events = {};
  }
  on(eventName, callback) {
    if(!this.events[eventName]) {
        this.events[eventName] = []
    }
    // 添加回调
    this.events[eventName].push(callback);
  }
  emit(eventName, ...args) {
    if(!this.events[eventName]) return
    this.events[eventName].forEach((fn) => {
      fn(...args);
    });
  }
  off(eventName, callback) {
    if (callback) {
      this.events[eventName] = this.events[eventName].filter(
        (fn) => fn !== callback
      );
    } else {
      delete this.events[eventName];
    }
  }
  once(eventName, callback) {
    // 1. 创建包装函数
    const onceFn = (...args) => {
        // 3. 执行原始回调
      callback(...args);
       // 4. 执行后立即取消订阅自身
      this.off(eventName, onceFn);
    };
    // 2. 注册包装函数
    this.on(eventName,onceFn)
  }
}
